//
//  main.m
//  objc_test
//
//  Created by Clover on 2021/7/21.
//

#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <objc/message.h>
#import <malloc/malloc.h>
#import "NSObject-internal.h"

extern uintptr_t _objc_rootRetainCount(id obj);
extern void _objc_autoreleasePoolPrint(void);

#import "Person.h"
#import "YBBlock.h"

//int clo_new_add(int a, int b){
//    NSLog(@"%d + %d = %d", a, b, a+b);
//    return a+b;
//}
//
//void YB_block_test(void){
//    void(^__weak doWork)(void) = nil;
//    {
//        int a = 0;
//        void(^ __weak doWork1)(void) = ^{ // stack 正常打印
//            a;
//            NSLog(@"111");
//        };
////        void(^ doWork1)(void) = ^{ // EXC_BAD_ACCESS
////            a;
////            NSLog(@"111");
////        };
//        doWork = doWork1;
//    }
//    doWork();
//}
//
//
//void yb_personRun(){
//    Person *person = [Person new];
//    [person performSelector:@selector(run)];
//}
//
//void charesvole(char * cha){
//    char *begin = cha;
//    char *end = cha + strlen(cha) - 1;
//    while (begin < end) {
//        char tmp = *begin;
//        *(begin) = *end;
//        *(end--) = tmp;
//    }
//}
void testAutoreleasePool(){
    //pool1，里面添加1个自动释放对象
      @autoreleasepool {
          NSObject *obj = [[NSObject alloc] autorelease];
          //pool2，里面添加3个自动释放对象
          @autoreleasepool {
              NSInteger count = 3;
              for(NSInteger i=0; i<count; i++){
                  NSObject *obj = [[NSObject alloc] autorelease];
              }
              //pool3，里面添加2个自动释放对象
              @autoreleasepool {
                  NSInteger count = 2;
                  for(NSInteger i=0; i<count; i++){
                      NSObject *obj = [[NSObject alloc] autorelease];
                  }
                  //创建完三个pool后打印
                  _objc_autoreleasePoolPrint();
              }
              //超出pool3的作用域时打印
              _objc_autoreleasePoolPrint();
          }
          //超出pool2的作用域时打印
          _objc_autoreleasePoolPrint();
      }
      //超出pool1作用域打印
      _objc_autoreleasePoolPrint();
}



int main(int argc, const char * argv[]) {
    @autoreleasepool {
        _objc_autoreleasePoolPrint();
//        charesvole("hello,world");
        int a = 10;
        __block int b = 20;
        Person *obj  = [[Person alloc] init];
        [obj personRun];
        
        
        testAutoreleasePool();
        obj.name = @"aa";
//        [obj printAllMethods];
//        [obj performSelector:@selector(yb_run)];
//        [obj performSelector:@selector(run)];
//        [Person yb_metalRun];
//        void (^myblock)(int value, int value2) = ^(int value, int value2) {
//            NSLog(@"%d + %d = %d", value, value2, value + value2);
//            value2 = 10;
//            NSLog(@"%d + %d = %d", value, value2, value + value2);
//            clo_new_add(a, b);
//        };
        void(^block)(void) = ^{
            NSLog(@"00");
        };
        NSLog(@"%@",block);
//        NSLog(@"%p,%@ - %@",obj,obj, obj.name);
//        void(^__weak objBlock)(void) = ^{
////            obj.name = @"bb";
//            NSLog(@"%p,%@ - %@",obj,obj, obj.name);
////            obj = [[Person alloc] init];
//            obj.name = @"bb";
//        };
//        objBlock();
//        NSLog(@"%p,%@ - %@",obj,obj, obj.name);
//
//        void(^block)(void) = [objBlock copy];
//        NSLog(@"%@ %@ - %@",block, obj, obj.name);
////        myblock(a,b);
//
//
//
//        NSObject *obj = [NSObject alloc];
//        Person *zhang3 = [Person alloc];
//        ((id(*)(id, SEL))objc_msgSend)(Person.class, @selector(alloc));
//        NSLog(@"%p --> %@", &zhang3, zhang3);
//        NSLog(@"obj_size:%zu, getIns:%zu , malloc: %zu", sizeof(obj), class_getInstanceSize(obj.class), malloc_size((__bridge const void *)(obj)));
//        NSLog(@"person_size:%zu, getIns:%zu , malloc: %zu", sizeof(zhang3), class_getInstanceSize(zhang3.class), malloc_size((__bridge const void *)(zhang3)));

//        YB_block_test();
//        yb_personRun();
//        Person *person = [Person new];
//        [person performSelector:@selector(run)];
        
//        id __weak weakObj = obj;
//        YBBlock *block = [YBBlock new];

    }
    return 0;
}





